import os
import sys
import json
import queue
from simpletcp.tcpserver import TCPServer


server_path = sys.path[0]
data_path = os.path.join(server_path, "data")
round_path = os.path.join(data_path, "round")
rankings_path = os.path.join(data_path, "rankings.json")

UTF_8 = "utf8"


def loadRounds(abspath: str):  # 从文件夹下的不同json文件中载入关卡列表
    if not os.path.isdir(abspath):
        os.makedirs(abspath)

    filename_list = os.listdir(abspath)
    filename_list.sort()
    item_list = list()

    for name in filename_list:
        json_path = os.path.join(abspath, name)

        if not os.path.isfile(json_path):
            file = open(json_path, mode="w", encoding=UTF_8)
            file.close()

        with open(json_path, encoding=UTF_8) as f:
            item = json.load(f)
            item_list.append(item)
    return item_list


round_list = loadRounds(round_path)
# print(round_list, end="\n"+"*"*40)


def loadRanking(abspath: str):  # 从文件中载入排行榜记录
    round_name_list = os.listdir(round_path)
    round_name_list.sort()
    ranking_dict = dict()

    if not os.path.isfile(abspath):
        value = list()
        for round_name in round_name_list:
            key = round_name.split('.')[0][-1]
            ranking_dict[key] = value
        with open(abspath, mode="w", encoding=UTF_8) as f:
            f.write(json.dumps(ranking_dict))
    else:
        with open(abspath, encoding=UTF_8) as f:
            ranking_dict = json.load(f)

    return ranking_dict


rankings_dict: dict = loadRanking(rankings_path)
# print(rankings_dict, end="\n"+"*"*40)


GET_ROUND_REQUEST = "Round"
GET_ROUND_NUM_REQUEST = "RoundNum"
GET_RANKING_REQUEST = "Ranking"
ADD_RANKING_REQUEST = "AddRanking"
EXIT_REQUEST = "Exit"
NONE_REQUEST = "None"

OPERATION_FIELD = "Operation"
INDEX_FIELD = "Index"
USERNAME_FIELD = "Username"
RECORD_FIELD = "Record"
RECORD_INDEX_FIELD = "RoundIndex"
RECORD_STAR_FIELD = "StarNumber"
RECORD_TIME_FIELD = "Time"
RECORD_STEP_FIELD = "Step"


def updateRanking(name, record: dict):
    index: int = record[RECORD_INDEX_FIELD]
    if len(rankings_dict) > index:
        record.pop(RECORD_INDEX_FIELD)
        record[USERNAME_FIELD] = name
        for item in rankings_dict[str(index)]:
            if item[USERNAME_FIELD] == record[USERNAME_FIELD]:
                return False
        rankings_dict[str(index)].append(record)
        rankings_dict[str(index)].sort(
            key=lambda x: (x[RECORD_TIME_FIELD]), reverse=True)
        rankings_dict[str(index)].sort(key=lambda x: (
            x[RECORD_STAR_FIELD], x[RECORD_STEP_FIELD]))
        with open(rankings_path, mode="w", encoding=UTF_8) as f:
            f.write(json.dumps(rankings_dict))
        return True
    return False


def read_callback(ip, queue, data):
    json_str = format(data.decode(UTF_8))
    request = json.loads(json_str)
    print(request)
    if(str(request[OPERATION_FIELD]) == GET_ROUND_NUM_REQUEST):
        result = dict()
        r_list = loadRounds(round_path)
        result[GET_ROUND_NUM_REQUEST] = len(r_list)
        callback = bytes(json.dumps(result), encoding=UTF_8)
        print(callback)
        queue.put(callback)
        return
    elif(str(request[OPERATION_FIELD]) == GET_ROUND_REQUEST):
        r_list = loadRounds(round_path)
        callback = bytes(json.dumps(r_list), encoding=UTF_8)
        queue.put(callback)
        print(r_list)
        return
    elif(str(request[OPERATION_FIELD]) == GET_RANKING_REQUEST):
        index: int = request[INDEX_FIELD]
        if len(rankings_dict) > index:
            print(json.dumps(rankings_dict[str(index)]))
            queue.put(
                bytes(json.dumps(rankings_dict[str(index)]), encoding=UTF_8))
            return
    elif(str(request[OPERATION_FIELD]) == ADD_RANKING_REQUEST):
        if updateRanking(request[USERNAME_FIELD], request[RECORD_FIELD]):
            queue.put(bytes("OK", encoding=UTF_8))
        else:
            queue.put(bytes("Fail", encoding=UTF_8))
        return
    elif(str(request[OPERATION_FIELD]) == EXIT_REQUEST):
        sys.exit()
    queue.put(bytes("None", encoding=UTF_8))


server = TCPServer("192.168.2.4", 5000, read_callback)
server.run()
